<?php

namespace app\test\controller;
use think\Controller;
use think\Config;
use think\Db;
use app\api\model\User;
//use think\Loader;


/**
 * Created by SimplerWorker
 * User: xiaojun.lan
 * Date: 2018/5/7
 * Time: 13:40
 */
class Test extends Controller
{

    public function __construct($type='json')
    {
        if(!in_array($type,['json','xml','jsonp'])){
            $type = 'json';
        }
        Config::set('default_return_type',$type);
    }

    public function index(){
        return 'api index index';
    }

    public function getUserInfo(){

        $data = [
            'code'=>200,
            'result'=>[
                'username'=>'xiaojun.lan',
                'useremail'=>'1888888@qq.com'
            ]
        ];
        return $data;
    }

    /**
     * 原生查询SQL
     */
    public function query(){
        $query = Db::query("select * from sw_user");
        dump($query);
    }

    /**
     * 原生执行SQL
     */
    public function execute(){
        $execute = DB::execute("insert into sw_user(name,password,email )
          values ('arjun','".md5('arjun')."','arjun@qq.com')");
        dump($execute);
    }

    /**
     * 四种查询SQL方式
     */
    public function select(){
        # 单实例,需要些表前缀
//        $db = Db::table('sw_user');
        # 单实例,不需要写表前缀
        $db = Db::name('user');

        # select 无论数据有多少条,都返回数组(没有数据返回时返回空数组[])
//        $res = $db->where('id=3')->select();

        # column 获取某个列的值:查询一个字段时,返回数组;查询多个字段时,返回对象;不管查询多少个字段,没有值时返回空数组
//        $res = $db->where('id=8')->column('password,email');

        # value 获取某个字段的值:只能查询一个字段,填写多个字段时,默认查询第一个字段值,返回字符串;查询不到数据时,返回null
//        $res = $db->where('id=8')->value('password');

        # find 返回一条数据,默认返回升序的第一条(最小的那条);查询不到数据时,返回null
        $res = $db->find();

        return $res['name'];

    }

    /**
     * 三种插入方式
     */
    public function insert(){
        $value = [];
        for($i = 0;$i < 30;$i++){
            $value[$i]['name'] = 'ajun'.$i;
            $value[$i]['password'] = md5('ajun'.$i);
            $value[$i]['email'] = 'ajun'.$i.'@qq.com';
            $value[$i]['count'] = $i+10;
        }
        $db = Db::name('user');

        # insert 只能插入一条数据,返回插入条数1;没有数据插入时,返回0
//        $res = $db->insert($value);

        # insertAll 批量插入数据,返回插入条数;没有数据插入时,返回false
        $res = $db->insertAll($value);

        return $res;
    }

    /**
     * 修改数据库
     * @return int|true
     */
    public function update(){
        $db = Db::name('user');

        # update 没有where条件时,会报错,返回被影响的行数,update只能传入数组
//        $res = $db->where('id<4')->update(['name'=>'<script>alert(1);</script>','email'=>'haha@qq.com']);

        # setField 需要where条件,返回被影响的行数,setField可以传入字符串和数组
        $res = $db->where('id < 4 ')->setField(['name'=>'<script>alert(1);</script>','email'=>'haha@qq.com']);

        # setInc count 字段必须为数字类型,执行一次,增加$step
        $step = 6;
//        $res = $db->where(['id'=>1])->setInc('count',$step);

        # setDec count字段必须为数字类型,执行一次,减少$step,当count的值小于最小值时,将会报错
//        $res = $db->where(['id'=>1])->setDec('count',$step);


        return $res;

    }

    /**
     * 删除记录
     */
    public function delete(){
        $db = Db::name('user');
//        $res = $db->delete(13); // 根据主键删除
//        $res = $db->delete([1,2]); // 根据主键删除
        $res = $db->where('id','eq',1)->delete(); // 根据条件删除
        return $res;

    }

    /**
     * 条件语句
     */
    public function where(){

        # 备注
        # EQ            相当于 =
        # NEQ           相当于 <>
        # LT            相当于 <
        # ELT           相当于 <=
        # GT            相当于 >
        # EGT           相当于 >=
        # BETWEEN       相当于  BETWEEN * AND *
        # NOTBETWEEN    相当于  NOTBETWEEN * AND *
        # IN            相当于  IN(*,*)
        # NOTIN         相当于  NOT IN(*,*)

        $db = Db::name('user');

        $sql = $db
            ->where('id','in','1,2,3')
            ->whereOr('name','eq','ajun')
            ->whereOr('count','lt','10')
            ->where('email','ajun5@qq.com')
            ->buildSql();

        dump($sql);
    }

    /**
     * SQL链式操作
     */
    public function lineSql(){
        $db = Db::name('user');
        $res = $db->where('id','>','10')
            ->field('name','id')
            ->order('id DESC')
//            ->limit(3) // limit(3,5)计算方式: limit((3-1)*5,5) , 建议使用page来分页
            ->page(2,5)
//            ->group("`group`") //分组,启用时,order和limit\page就不起作用
            ->select();
        dump($res);

    }

    /**
     * 模型基础方法
     */
    public function module(){
        # use app\api\model 方式,需要有app\api\model\User.php空模型类存在
        $res = User::get(22);

        # use think\Loader 方式
//        $user = Loader::model('user');
//        $res = $user::get(4);

        # 直接使用 model 方式,助手函数
//        $user = model('user');
//        $res = $user->get(4);

        return $res;

    }

    /**
     * 模型查询数据
     */
    public function moduleSelect(){
        # 需要引入 app\api\model\User;

        # 传递方法类查询(闭包函数)
       /* $res = User::get(function ($query){
            $query->where('name','eq','ajun21')
                ->field('name,email,password');
        });*/

       # 使用模型条件直接查询
        /*$res = User::where("id",15)
            ->field("id,name,email")
            ->find();*/

        # 使用all直接获取id为11,14,15的数据记录
//        $res = User::all("11,14,15"); // 方式一
//        $res = User::all([11,14,15]); // 方式二
        /*$res = User::all(function ($query){ // 方式三,使用闭包函数
            $query->where('id','<',15)
                ->field('id,name,email');
        });*/

        # value方法,获取字段对应的值,返回字符串,只能获取一个字段,value中多传入的值无效,只获取第一个
//        $res = User::where('id',22)->value('email');

        # column方法获取列,可以传入多列或数组
//        $res = User::column('name,email'); // 字符串形式
        $res = User::column(['name','email']); // 数组形式

        return $res;

    }

    /**
     * 模型添加数据
     */
    public function moduleInsert(){
        # 需要引入 app\api\model\User;
        # 使用create方法添加,可添加过滤字段规则
       /* $res = User::create([ // 方法一
            'name'=>'create',
            'password'=>md5('create'),
            'count'=>5,
            'demo'=>123
        ],true); // 当表中不存在demo字段时,第二个参数为true,将自动过滤数据,插入表中有的字段*/

        /*$res = User::create([ // 方法二
            'name'=>'create',
            'password'=>md5('create'),
            'count'=>5,
            'demo'=>123
        ],['name','email']); // 第三个参数限制了只将name和email字段对应的值插入表,其余的字段将会被过滤*/

       # 使用User对象插入数据
        /*$userModel = new User();
        $userModel->name = 'newUserModel';
        $userModel->email = 'newUserModel@qq.com';
        $userModel->password = md5('newUserModel');
        $res = $userModel->save();*/

        # 使用链式操作过滤字段
        $userModel = new User();
        $res = $userModel->allowField(true) // 允许自动过滤字段,为数组时,只添加数组中的字段
        ->save([
            'name' => 'allowField',
            'password' => md5('allFeild'),
            'demo' => '1234asdf'
        ]);

        return $res;

    }

    /**
     * 模型更新数据
     */
    public function moduleUpdate(){
        # 需要引入 app\api\model\User;

        # update 方式更新数据 , 返回影响条数
       /* $res = User::update([ // 方法一,返回 {'name'=>'moduleUpdate'} 对象
            'name'=>'moduleUpdate'
        ],['id'=>6]);*/

      /* $res = User::update([ // 方法二(使用闭包函数),返回 {'name'=>'moduleUpdateQeury'} 对象
           'name'=>'moduleUpdateQeury'
       ],function($query){
           $query->where('id','LT',6);
       });*/

      # 使用where查询更新 , 返回影响条数
       /* $res = User::where('id','<','10')
            ->update([
                'name' => 'whereUpdate'
            ]);*/

      # 使用User对象更新函数,相应id记录不存在时,将会报错
       /* $userModel = User::get(11); // 获取id为1的记录
        $userModel->name = 'moduleUpdate';
        $userModel->email = "moduleUpdate@qq.com";
        $res = $userModel->save(); // 将id为1的记录更新*/

       # 使用模型对象save更新数据 , 返回被更新的条数
        $userModel = new User();
//        $res = $userModel->save([ // 方法一,使用第二个参数条件判断
//           'name'=>'moduleUpdateSave'
//        ],['name'=>'ajun10']);

        $res = $userModel->save([ // 方法二,第二个参数使用闭包函数判断
            'name'=>'moduleUpdateSaveBBHS'
        ],function($query){
            $query->where('id','LT','10');
        });

        return $res;

    }

    /**
     * 模型删除数据
     */
    public function moduleDelete(){
        # 需要引入 app\api\model\User;
        # 使用destroy方法删除,记录不存在将报错
//        $res = User::destroy(11); // 方法一,删除id为11的数据
//        $res = User::destroy(['id'=>6]); // 方法二,删除id为6的数据
       /* $res = User::destroy(function($query){ // 方法三,使用闭包函数删除多条记录
            $query->where('id','<',10);
        });*/

       # 使用对象delete方法删除,返回被删除的记录,记录不存在将报错
//        $userModule = User::get(14);
//        $res = $userModule->delete();

        # 使用对象where条件进行删除
//        $res = User::where('id',15)->delete(); // 删除id为5的记录
//        $res = User::where('id','<',20)->delete(); // 删除id小于20的记录
        $res = User::where('1=1')->delete(); // 删除表中所有纪录

        return $res;

    }

    /**
     * 模型聚合操作
     */
    public function modulePloy(){
        # 需要引入 app\api\model\User;
//        $res = User::count(); // 获取表中数据总条数
//        $res = User::where("id",">",5)->count();
//        $res = User::max('count'); // 获取表中count字段最大的数值
//        $res = User::where('id','<',4)->max('count');
//        $res = User::sum('count'); // 计算count的总和
//        $res = User::where('id','<','3')->sum('count');
//        $res = User::avg('count'); // 求表字段count的平均值
//        $res = User::min('count');// 求表字段count的最小值
        $res = User::where('id','>',10)->min('count');


        return $res;

    }

    /**
     * 模型获取器,例如,表中保存性别为:0:男;1:女,如何获取这样的数据， 需要在模型中做设置
     */
    public function moduleReplace(){
        # 需要引入 app\api\model\User;
        $res = User::get(2);

//        return $res->sex; // 替换后的值
//        return $res->toArray(); // 替换数据后的整条数据(只将sex替换为男或女)
        return $res->getData(); // 获取整条原始数据

    }

    /**
     * 模型增加属性，演示模型中定义记录增加时，表对应字段值可自动增加设置值
     * @return $this
     */
    public function moduleAddAttr(){
        $res = User::create([
            'name' => 'ajun',
            'password' =>'ajun',
            'email' => 'ajun@qq.com',
            'count' => 3
        ]);

        return $res;
    }

    /**
     * 模型修改属性，演示了模型中更新时，表对应字段值自动更新为设置值属性
     * @return $this
     */
    public function moduleUpdateAttr(){
        $res = User::update([
            'name' => 'xiaojun'
        ],function($query){
            $query->where('email','ajun@qq.com');
        });

        return $res;

    }

    /**
     * 模型删除属性，演示软删除（没有实际删除，而是设置delete_time的值）和硬删除（实际从表中删除）
     * @return int
     */
    public function moduleDeleteAttr(){
        # 使用destroy进行软删除，前提时module中设置了  protected $deleteTime = 'delete_time';
//        $res = User::destroy(1); // 软删除，实际并不删除这条记录，而是将delete_time设置值
//        $res = User::destroy(1,true); // 硬删除，将这条记录从表中彻底删除
       /* $res = User::destroy(function ($query){ // 软删除，删除多条记录
           $query->where('id','>',7);
        });*/

        # 使用delete进行软删除，前提时module中设置了  protected $deleteTime = 'delete_time';
        $user = User::get(2); // get 助手函数只获取一条数据，不适用于闭包函数
        $res = $user->delete(); // 软删除，实际并不删除这条记录，而是将delete_time设置值
//        $res = $user->delete(true); //  硬删除，将这条记录从表中彻底删除


        ###### 软删除功能不可使用这种方式进行删除start################################################################
        ###//$res = User::where('id','3')->delete(); // 这样没有软删除，会直接将数据从表中删除，软删除不要使用这种方法###
        ###### 软删除功能不可使用这种方式进行删除end##################################################################

        return $res;

    }

    /**
     * 模型查询属性，演示了只查询没有删除、只查询软删除、查询软删除和未删除的方法
     * @return false|static[]
     */
    public function moduleSelectAttr(){
//        $res = User::get(1); // 获取没有软删除的数据
//        $res = User::withTrashed(true)->select(3); // 可获取包含软删除和非删除的数据

//        $res = User::onlyTrashed()->select(); // 获取所有已经软删除的数据
        $res = User::all(); // 获取所有没有软删除的数据

        return $res;

    }

}

